//!
/************************************************************************************************************
 * @file RBSystem_Win32.cpp
 ************************************************************************************************************/

/************************************************************************************************************
 * Precompiled Header
 ************************************************************************************************************/
#include "RBMainPCH.h"

/************************************************************************************************************
 * Includes
 ************************************************************************************************************/

#include "RBMain/RBSystem.h"
#include "RBMain/RBMemoryManagerOff.h"
#include <Windows.h>
#include <io.h>
#include <dirent.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
#include "RBMain/RBMemoryManagerOn.h"

/************************************************************************************************************
 * Defines
 ************************************************************************************************************/

namespace RBSystem
{

/***********************************************************************************************************
 * 
 ***********************************************************************************************************/
void GetCursorPos(int32& x, int32& y)
{
    POINT winPos;
    ::GetCursorPos(&winPos);
    x = winPos.x;
    y = winPos.y;
}

/***********************************************************************************************************
 * 
 ***********************************************************************************************************/
void SetCursorPos(int32 x, int32 y)
{
    ::SetCursorPos(x, y);
}

/***********************************************************************************************************
 *
 ***********************************************************************************************************/
void Sleep(int32 ms)
{
    ::Sleep(ms);
}

/***********************************************************************************************************
 *
 ***********************************************************************************************************/
uint32 Rand()
{
    return ::rand();
}

/***********************************************************************************************************
 *
 ***********************************************************************************************************/
void SetCapture(void* pWindow)
{
    ::SetCapture((HWND)pWindow);
}

/***********************************************************************************************************
*
***********************************************************************************************************/
void ReleaseCapture()
{
    ::ReleaseCapture();
}

namespace File
{

    
/***********************************************************************************************************
 * 
 ***********************************************************************************************************/
bool Exists(const RBString& strFile)
{
    return _access(strFile.c_str(), 0) == 0;
}


/***********************************************************************************************************
 * 
 ***********************************************************************************************************/
void ParseDirectory(const RBString& strDir, const FileIterator& iter, const RBString& strFilter)
{
    RBString strPatternToFind = strDir + "/" + strFilter;
    DIR *dir;
    struct dirent *ent;
    std::deque<RBString> directoriesToScan;
    directoriesToScan.push_back(strDir);
    while (!directoriesToScan.empty())
    {
        RBString strCurrentDir = directoriesToScan.front();
        directoriesToScan.pop_front();
        dir = opendir (strCurrentDir.c_str());
        if (dir != NULL)
        {
            /* print all the files and directories within directory */
            while ((ent = readdir (dir)) != NULL) 
            {
                if ((ent->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
                {
                    if ((ent->data.cFileName[0] != '.') && const_cast<FileIterator&>(iter).OnDir(ent->data.cFileName))
                    {
                        directoriesToScan.push_back(strCurrentDir + "/" + ent->data.cFileName);
                    }
                }
                else if (PathMatchSpec(ent->d_name, strFilter.c_str()))
                {
                    const_cast<FileIterator&>(iter).OnFile(strCurrentDir + "/" + ent->data.cFileName);
                }
            }
            closedir (dir);
        }
    }
}

/************************************************************************************************************/
}
}